﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.ServiceModel;

namespace BilingualSentSearchEngine
{
    class IndexingServiceProxy
    {
        private static List<IBilingualSentIndexingService> indexingServiceProxyList;

        public IndexingServiceProxy(string[] astrIndexingServiceList)
        {
            
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
            basicHttpBinding.MaxBufferPoolSize = 1024 * 1024;
            basicHttpBinding.MaxBufferSize = 1024 * 1024 * 4;
            basicHttpBinding.MaxReceivedMessageSize = 1024 * 1024 * 4;
            basicHttpBinding.SendTimeout = new TimeSpan(0, 10, 0);
            basicHttpBinding.MessageEncoding = WSMessageEncoding.Mtom;

            indexingServiceProxyList = new List<IBilingualSentIndexingService>();
            foreach (string item in astrIndexingServiceList)
            {
                string strServiceAddr;
                strServiceAddr = item.Trim();
                if (strServiceAddr.Length > 0)
                {
                    IBilingualSentIndexingService proxy;
                    proxy = ChannelFactory<IBilingualSentIndexingService>.CreateChannel(basicHttpBinding, new EndpointAddress(strServiceAddr));
                    indexingServiceProxyList.Add(proxy);
                }
            }
        }

        public List<SentencePair> MergeSentencePair(List<SentencePair> src1, ref List<SentencePair> src2)
        {
            List<SentencePair> dest = new List<SentencePair>();

            int i, j;
            i = 0;
            j = 0;
            while (i < src1.Count && j < src2.Count)
            {
                if (src1[i].score < src2[j].score)
                {
                    dest.Add(src1[i]);
                    i++;
                }
                else if (src1[i].score > src2[j].score)
                {
                    dest.Add(src2[j]);
                    j++;
                }
                else if (src1[i].score == src2[j].score)
                {
                    dest.Add(src1[i]);
                    dest.Add(src2[j]);
                    i++;
                    j++;
                }
            }

            if (i < src1.Count)
            {
                dest.AddRange(src1.GetRange(i, src1.Count - i));
            }
            if (j < src2.Count)
            {
                dest.AddRange(src2.GetRange(j, src2.Count - j));
            }

            return dest;
        }


        public List<SentencePair> QuerySentencePairByEnglish(ref string strQuery, int topN)
        {
            Dictionary<IAsyncResult, IBilingualSentIndexingService> ar2proxy = new Dictionary<IAsyncResult, IBilingualSentIndexingService>();
            List<SentencePair> sentPairList = new List<SentencePair>();
            foreach (IBilingualSentIndexingService proxy in indexingServiceProxyList)
            {
                try
                {
                    IAsyncResult result = proxy.BeginQuerySentencePairByEnglish(strQuery, topN, null, null);
                    ar2proxy.Add(result, proxy);
                }
                catch (System.Exception err)
                {


                }
            }
            foreach (KeyValuePair<IAsyncResult, IBilingualSentIndexingService> pair in ar2proxy)
            {
                try
                {
                    List<SentencePair> tmp;
                    pair.Key.AsyncWaitHandle.WaitOne();
                    tmp = pair.Value.EndQuerySentencePairByEnglish(pair.Key);
                    sentPairList = MergeSentencePair(sentPairList, ref tmp);
                }
                catch (System.Exception err)
                {


                }
            }

            return sentPairList;
        }

        public List<SentencePair> QuerySentencePairByChinese(ref string strQuery, int topN)
        {
            Dictionary<IAsyncResult, IBilingualSentIndexingService> ar2proxy = new Dictionary<IAsyncResult, IBilingualSentIndexingService>();
            List<SentencePair> sentPairList = new List<SentencePair>();
            foreach (IBilingualSentIndexingService proxy in indexingServiceProxyList)
            {
                try
                {
                    IAsyncResult result = proxy.BeginQuerySentencePairByChinese(strQuery, topN, null, null);
                    ar2proxy.Add(result, proxy);
                }
                catch (System.Exception err)
                {


                }
            }
            foreach (KeyValuePair<IAsyncResult, IBilingualSentIndexingService> pair in ar2proxy)
            {
                try
                {
                    List<SentencePair> tmp;
                    pair.Key.AsyncWaitHandle.WaitOne();
                    tmp = pair.Value.EndQuerySentencePairByChinese(pair.Key);
                    sentPairList = MergeSentencePair(sentPairList, ref tmp);
                }
                catch (System.Exception err)
                {


                }
            }


            return sentPairList;

        }


      


        public List<SentencePair> QuerySentencePairByJapanese(ref string strQuery, int topN)
        {
            Dictionary<IAsyncResult, IBilingualSentIndexingService> ar2proxy = new Dictionary<IAsyncResult, IBilingualSentIndexingService>();
            List<SentencePair> sentPairList = new List<SentencePair>();
            foreach (IBilingualSentIndexingService proxy in indexingServiceProxyList)
            {
                try
                {
                    IAsyncResult result = proxy.BeginQuerySentencePairByJapanese(strQuery, topN, null, null);
                    ar2proxy.Add(result, proxy);
                }
                catch (System.Exception err)
                {


                }
            }
            foreach (KeyValuePair<IAsyncResult, IBilingualSentIndexingService> pair in ar2proxy)
            {
                try
                {
                    List<SentencePair> tmp;
                    pair.Key.AsyncWaitHandle.WaitOne();
                    tmp = pair.Value.EndQuerySentencePairByJapanese(pair.Key);
                    sentPairList = MergeSentencePair(sentPairList, ref tmp);
                }
                catch (System.Exception err)
                {


                }
            }

            return sentPairList;
        }
    }
}
